﻿using BCCommon;
using BCCommon.Enums;
using BCData.Website.User.User;
using BCData.Website.User.UserAuth;
using BCDto.Website.UserAuth;
using BCEntity.Common.EntityNameConst;
using BCEntity.Website.User;
using BCService.Utils;
using System;
using System.Collections.Generic;

namespace BCService.Website.UserAuth
{
    public class UserAuthService : IUserAuthService
    {
        private readonly IDatabaseContext databaseContext;
        private readonly IApplicationContextService applicationContextService;
        private readonly IRedisService redisService;
        private readonly IUserAuthData userAuthData;
        private readonly IUserData userData;
        private readonly string key = string.Format("{0}", EntityNameConst.UserAuthEntity);

        public UserAuthService(IDatabaseContext databaseContext,
            IApplicationContextService applicationContextService,
            IRedisService redisService,
            IUserAuthData userAuthData,
            IUserData userData)
        {
            this.databaseContext = databaseContext;
            this.applicationContextService = applicationContextService;
            this.redisService = redisService;
            this.userAuthData = userAuthData;
            this.userData = userData;
        }

        #region 检查信息是否存在
        public bool Exists(long userAuthId)
        {
            return this.userAuthData.Exists(userAuthId).GetAwaiter().GetResult();
        }
        #endregion

        #region 添加信息
        public UserAuthDto Add(UserAuthRequestDto requestDto)
        {
            
            if (!this.userData.CheckUserId(requestDto.UserId).Result)
            {
                throw new ArgumentException("此用户信息不存在!");
            }
            if (this.userAuthData.Exists(requestDto.AuthType, requestDto.UnionId).Result)
            {
                return this.userAuthData.GetEntity(requestDto.AuthType, requestDto.UnionId).Result.As<UserAuthDto>();
            }
            var entity = requestDto.As<UserAuthEntity>();

            return this.userAuthData.Add(entity).GetAwaiter().GetResult().As<UserAuthDto>();
        }
        #endregion

        #region 修改信息
        public UserAuthDto Update(UserAuthPutDto putDto)
        {
            if (!this.Exists(putDto.UserAuthId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            if (!this.userData.CheckUserId(putDto.UserId).Result)
            {
                throw new ArgumentException("此用户信息不存在!");
            }
            if (this.userAuthData.Exists(putDto.AuthType, putDto.UnionId).Result)
            {
                var oldEntity = this.userAuthData.GetEntity(putDto.AuthType, putDto.UnionId).Result;
                if (oldEntity.UserId != putDto.UserId)
                {
                    throw new ArgumentException("此授权信息已绑定其他用户，无法同时绑定多人!");
                }
            }
            var entity = putDto.As<UserAuthEntity>();

            var result = this.userAuthData.Update(entity).GetAwaiter().GetResult().As<UserAuthDto>();
            string cacheKey = this.redisService.GetKey(key, entity.UserAuthId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 删除信息
        public void Delete(long userAuthId)
        {
            if (!this.Exists(userAuthId))
            {
                throw new ArgumentException("此记录不存在!");
            }

            this.userAuthData.Delete(userAuthId);
            string cacheKey = this.redisService.GetKey(key, userAuthId);
            this.redisService.DeleteAsync(cacheKey);
        }
        #endregion

        #region 获取信息
        public UserAuthDto Get(AuthType authType,string unionId)
        {
            string cacheKey = this.redisService.GetKey(key, unionId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.userAuthData.GetEntity(authType,unionId).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromMinutes(30));
            return result.As<UserAuthDto>();
        }
        #endregion

        #region 获取信息列表
        public IEnumerable<UserAuthDto> GetList(long userId)
        {
            string cacheKey = this.redisService.GetKey(key, userId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                return this.userAuthData.GetList(userId).GetAwaiter().GetResult();
            }, TimeSpan.FromMinutes(30));
            return result.As<IEnumerable<UserAuthDto>>();
        }
        #endregion

    }
}